package com.googlecode.horncomb.web.spring.context;

import java.io.IOException;
import java.util.logging.LogRecord;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class SpringContextLocatingFilter implements Filter,
        java.util.logging.Filter
{
    private static Log log = LogFactory
            .getLog(SpringContextLocatingFilter.class);
    private boolean loadOnRequest = false;

    public void destroy()
    {
        SpringContextLocator.setRootApplicationContext(null);
    }

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException
    {
        try
        {
            if (loadOnRequest && request instanceof HttpServletRequest)
            {
                WebApplicationContext ctx = WebApplicationContextUtils
                        .getRequiredWebApplicationContext(((HttpServletRequest) request)
                                .getSession().getServletContext());
                if (SpringContextLocator.getRootApplicationContext() == null)
                {
                    SpringContextLocator.setRootApplicationContext(ctx);
                }
                SpringContextLocator.setCurrentApplicationContext(ctx);
                log.debug("get ApplicationContext: " + ctx);
            }
            chain.doFilter(request, response);
        }
        finally
        {
            if (loadOnRequest)
            {
                SpringContextLocator.setCurrentApplicationContext(null);
            }
        }
    }

    public void init(FilterConfig config) throws ServletException
    {
        if (StringUtils.equals("true", config
                .getInitParameter("spring.context.locator.loadOnRequest")))
        {
            this.loadOnRequest = true;
        }

        if (!loadOnRequest)
        {
            WebApplicationContext ctx = WebApplicationContextUtils
                    .getRequiredWebApplicationContext(config
                            .getServletContext());
            if (ctx == null)
            {
                loadOnRequest = true;
            }
            else
            {
                SpringContextLocator.setRootApplicationContext(ctx);
            }
        }
    }

    public boolean isLoggable(LogRecord record)
    {
        return false;
    }

    public boolean isLoadOnRequest()
    {
        return loadOnRequest;
    }

    public void setLoadOnRequest(boolean loadByRequest)
    {
        this.loadOnRequest = loadByRequest;
    }

}
